package com.golang.api.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.JavaType;
import org.apache.commons.lang3.StringUtils;

/**
 * Json序列化和反序列化的助手类
 * 
 *
 * @author lijianzhong
 */
public class JsonHelper {

	private static JsonMapper jsonMapper;

	/**
	 * @param jsonMapper
	 *            the jsonMapper to set
	 */
	public static void setJsonMapper(JsonMapper jsonMapper) {
		JsonHelper.jsonMapper = jsonMapper;
	}

	/**
	 * 如果没有调用setJsonMapper设置JsonMapper, 则默认创建只输出非空属性到Json字符串的Mapper.
	 * 
	 * @return the JsonMapper
	 */
	private static JsonMapper getJsonMapper() {
		if (null != JsonHelper.jsonMapper) {
			return JsonHelper.jsonMapper;
		}
		return JsonMapper.buildNonNullMapper();
	}

	/**
	 * from bean to json
	 * 
	 * @param obj
	 *            the object
	 * @return the json string
	 */
	public static String toJson(Object obj) {
		return getJsonMapper().toJson(obj);
	}

	/**
	 * from json to bean
	 * 
	 * @param json
	 *            the json
	 * @param responseType
	 *            the java type
	 * @param <T>
	 *            the type of the class modeled by this {@code Class}
	 * @return the java t
	 */
	public static <T> T toBean(String json, Class<T> responseType) {
		return getJsonMapper().fromJson(json, responseType);
	}

	/**
	 * from json to collection bean
	 * 
	 * @param json
	 *            the json
	 * @param collectionClass
	 *            the collection class
	 * @param elementClasses
	 *            the element classes
	 * @return the java Object
	 */
	public static Object toCollectionBean(String json, Class<?> collectionClass, Class<?>... elementClasses) {
		JavaType javaType = getJsonMapper().constructParametricType(collectionClass, elementClasses);
		return getJsonMapper().fromJson(json, javaType);
	}

	/**
	 * from json to List bean
	 * 
	 * @param json
	 *            the json
	 * @param parameterClass
	 *            the parameter class
	 * @param <T>
	 *            the type of the class modeled by this {@code Class}
	 * @return the java List Object
	 */
	public static <T> List<T> toList(String json, Class<T> parameterClass) {
		JavaType javaType = getJsonMapper().constructParametricType(List.class, parameterClass);
		return getJsonMapper().fromJson(json, javaType);
	}

	/**
	 * from json to Map bean
	 * 
	 * @param json
	 *            the json
	 * @param keyClass
	 *            the parameter key class
	 * @param valueClass
	 *            the parameter value class
	 * @param <K>
	 *            the type of the class modeled by this {@code Class}
	 * @param <V>
	 *            the type of the class modeled by this {@code Class}
	 * @return the java Map Object
	 */
	public static <K, V> Map<K, V> toMap(String json, Class<K> keyClass, Class<V> valueClass) {
		JavaType javaType = getJsonMapper().constructParametricType(Map.class, keyClass, valueClass);
		return getJsonMapper().fromJson(json, javaType);
	}

    public static Map<String,Object> asMap(String content) {
        if (StringUtils.isBlank(content)) {
            return new HashMap<>();// 不要使用EMPTY_MAP
        }
        try {
            return getJsonMapper().getMapper().readValue(content, Map.class);
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

    public static <T> List<T> asList(String content) {
        if (StringUtils.isBlank(content)) {
            return new ArrayList<>();// 不要使用EMPTY_LIST
        }
        try {
            return getJsonMapper().getMapper().readValue(content, List.class);
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

}
